--作用仿真蛋的数据
require("luacom")--引用com插件
require('lfs')    --导入lfs模块用于取得当前路径，和操作EXCEL无关
local JsonParser=require("jsonParser")
local Tool=require("FUC")
local ExcelRoot = lfs.currentdir()    --取得当前路径 
ExcelRoot=Tool.GetPath(ExcelRoot,"..")

--[[ 创建excel对象 ----------]]
local excel = luacom.CreateObject("Excel.Application") --创建新的实例
local BoostSimBook = excel.WorkBooks:Open(ExcelRoot .. '\\SubExcel\\PET_BOOST.xls', 0, 0)    --打开EXCEL文件，应使用绝对路

SimSheet = BoostSimBook.Sheets("DATA")    --数据表
-- SimSheet = book.Sheets("Sim")    --生成仿真结果



local EggPetData_Cfg=require("EggPetData")
local LevelHatchEgg_Cfg=require("LevelHatchEgg")

-- local PetBoostSim_Sort={}
local PetValue_Cfg={}

for k,v in pairs(EggPetData_Cfg) do
	-- table.insert(PetBoostSim_Sort,v)
	for j,petId in pairs(v.petIds) do
		PetValue_Cfg[petId]=v.boostIds[j]
	end
end
-- table.sort(PetBoostSim_Sort,function(a,b) --sortId 表示摇蛋先后顺序，排序后使用
-- 	return a.sortId<b.sortId --越小越在前
-- end)

local EvolutionBoost={
    [1]=1,
    [2]=2,
    [3]=8,
}

local LevelBoost={
    [1]=1,
    [2]=2,
    [3]=4,
}

----------用户数据---模拟--------
local U_HadPet={}-- 背包中的宠物

-- probability:概率序列（越好的奖励，在数组的越后面）
--luck：幸运次数（取最好的结果）
function RandomLucky(probability,luck)
    if not luck then  --没有幸运值，默认为1
        luck=1
    end
    local sum=0 --概率和
	for k,p in pairs(probability) do
		sum=sum+p
	end
    local luckMax=0 --产生的最大幸运值
    for i=1,luck do
    	local a=math.random(0,sum)
        if a>luckMax then
            luckMax=a
        end
    end
    local s=0
	for k,p in pairs(probability) do
        s=s+p
		if luckMax<=s then
            return k,luckMax
        end
	end
	return 0,luckMax
end

function data2petId(id,level,evolution)
    if not level then
        level=1
    end

    if not evolution then
        evolution=1 
    end

    return  id.."_"..level.."_"..evolution
end
function petId2data(petId)
    local arg=string.split(petId,"_")
    if #arg==1 then
        return tonumber(arg[1]),1,1
    end

    if #arg==2 then
        return tonumber(arg[1]),tonumber(arg[2]),1
    end
    return tonumber(arg[1]),tonumber(arg[2]),tonumber(arg[3])
end

function GetBoostByPetId(petId)
	local id,level,	evolution=petId2data(petId)
	return PetValue_Cfg[id]*LevelBoost[level]*EvolutionBoost[evolution]
end


function MergeOne(petId,need,maxlv)
	local id,lv,en=petId2data(petId)
	if lv<maxlv then
		if U_HadPet[petId]<need then
			return false
		else
			local addCount=math.floor(U_HadPet[petId]/need)
			U_HadPet[petId]=U_HadPet[petId]-addCount*need
			local newPetId=data2petId(id,lv+1,en)
			if U_HadPet[newPetId] then
				U_HadPet[newPetId]=U_HadPet[newPetId]+addCount
			else
				U_HadPet[newPetId]=addCount
			end

			return true
		end
	else
		return false
	end
end

function MergeAll(need,maxlv)
	local isMerge=false
	for k,v in pairs(U_HadPet) do
		if MergeOne(k,need,maxlv) then
			isMerge=true
		end
	end
	if isMerge then
		MergeAll(need,maxlv)
	end
end

-- 获取背包的宠物数量
function GetPetCount()
	local sum=0
	for k,v in pairs(U_HadPet) do
		sum=sum+v
	end
	return sum
end

--移除N个最渣宠物
function RemoveLowPet(count)
	local sortList={}
	for k,v in pairs(U_HadPet) do
		local boost=GetBoostByPetId(k)
		table.insert(sortList,{
			petId=k,
			value=boost
		})
	end

	if #sortList>0 then
		--先排序
		table.sort(sortList, function(a,b)
			return a.value<b.value --小的在前面
		end)

		local NeedRemove=count
		for k,v in pairs(sortList) do
			if NeedRemove<=0 then
				return 
			end
			if U_HadPet[v.petId]<NeedRemove then
				NeedRemove=NeedRemove-U_HadPet[v.petId]
				U_HadPet[v.petId]=0
			else
				U_HadPet[v.petId]=U_HadPet[v.petId]-NeedRemove
				return
			end

		end
	end

end

--优化宠物背包
function Optimize(backpack,maxLevel,need)
	--先合成升级
	MergeAll(need,maxLevel)
	local petCount=GetPetCount()
	local removeCount=petCount-backpack
	if removeCount>0 then --  超出背包，剔除
		RemoveLowPet(removeCount)
	end
end

--获取最好的装备值
function GetBestEquip(equipMax) -- 最大装备数
	local sortList={}
	for k,v in pairs(U_HadPet) do
		local boost=GetBoostByPetId(k)
		table.insert(sortList,{
			petId=k,
			value=boost
		})
	end

	-- 排序
	if #sortList>0 then
		--先排序
		table.sort(sortList, function(a,b)
			return a.value>b.value 
		end)

		local equipData={}
		local NeedEquip=equipMax
		for k,v in pairs(sortList) do
			if NeedEquip<=0 then
				return equipData
			end
			if U_HadPet[v.petId]<NeedEquip then
				NeedEquip=NeedEquip-U_HadPet[v.petId]
				equipData[v.petId]=U_HadPet[v.petId]
			else
				equipData[v.petId]=NeedEquip
				return equipData
			end
		end
		return equipData
	else

		return {}

	end
end

--计算装备的加成值
function GetBoostByEquip(equipdata) 
    local sum=1
    for k,v in pairs(equipdata) do
    	sum=sum+GetBoostByPetId(k)*v
    end
	return sum
end

function Hatch(data)

	-- 获取摇到的宠物
	for i=1,data.hatchCount do
		local petIndex,luckMax=RandomLucky(data.probability,data.lucky)
		print("---Hatch-eggId：PetIndex：PetId->",data.id,petIndex,data.petIds[petIndex])
		local petId=data2petId(data.petIds[petIndex])
		--放入背包
		if not U_HadPet[petId] then
	 		U_HadPet[petId] =1
	 	else
			U_HadPet[petId]=U_HadPet[petId]+1
		end
	end
	
	-- 优化背包(合并，去除垃圾宠物)
	Optimize(data.backpack,data.maxLevel,data.merge)

	local equiData= GetBestEquip(data.equipMax)

	return GetBoostByEquip(equiData)
end


function HatchByLevelData(data)
		for k,eggId in pairs(data.eggList) do --遍历当前关卡摇蛋列表
			local eggcfg=EggPetData_Cfg[eggId]
			if not eggcfg then
				print("不存在蛋eggId->levelId:",eggId,data.id)
				return false
			end

			for j=1,data.hatchList[k] do --每颗蛋需要摇N次
				local petIndex,luckMax=RandomLucky(eggcfg.probability,data.lucky)
				local petId=data2petId(eggcfg.petIds[petIndex])
				--放入背包
				if not U_HadPet[petId] then
			 		U_HadPet[petId] =1
			 	else
					U_HadPet[petId]=U_HadPet[petId]+1
				end
			end
		end

		-- 关卡摇蛋完毕，合成宠物，优化背包

		-- 优化背包(合并，去除垃圾宠物)
		 Optimize(data.backpack,data.maxLevel,data.merge)
		 -- 获取装备数据
		 local equiData= GetBestEquip(data.equipMax)
		 -- 当前加成值
		 local boost=GetBoostByEquip(equiData)

		 return boost

end

local RandCount=10 --重复次数（求平均值）
local SR=4 --起始行
local SC=4 --起始列

local r=SR --行坐标
local c=SC --列坐标

for i=1,RandCount do
	U_HadPet={} --背包
	r=SR --行回归起始

	--模拟一次全关卡摇蛋
	for p,v in ipairs(LevelHatchEgg_Cfg) do
		print(p,v.id)
		local boost=HatchByLevelData(v)
		if not boost then
			break
		end
		SimSheet.Cells(r, c).Value2=boost
		-- print(string.format("egg:%d->Boost:%d",v.id,boost))
		print("EggID--boost-->:",v.id,boost)
		r=r+1
	end
	c=c+1
end

BoostSimBook:Save()
BoostSimBook:Close()

excel.DisplayAlerts = false
excel:Quit()